package com.goodfox.web.generic.provide.interceptor;

import java.lang.reflect.Field;
import java.util.Date;

import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.goodfox.web.generic.account.entity.Account;
import com.goodfox.web.generic.log.entity.OperatorLog;
import com.goodfox.web.generic.log.mapper.OperatorLogMapper;
import com.goodfox.web.generic.provide.annotation.DbEntity;
import com.goodfox.web.generic.provide.annotation.DbField;
import com.goodfox.web.generic.provide.annotation.NoteExplain;
import com.goodfox.web.generic.provide.util.UUIDUtil;

/**
 * Service日志拦截
 * @author qin gt
 *
 */
@Component
@Aspect
public class ServiceLoggingInterceptor {

	/** 日志器 */
	private Logger logger=Logger.getLogger(ServiceLoggingInterceptor.class);

	/** 日志Mapper */
	@Autowired
	private OperatorLogMapper logMapper;
	
	@AfterReturning("execution(* com.goodfox.*.*.*.service.impl.*.add*(..))")
	public void addLogging(JoinPoint jp){
		logger.debug("获取新增操作日志");
		OperatorLog log=new OperatorLog();
		log.setOpeLogId(UUIDUtil.getUUID());
	    log.setOpeService(String.valueOf(jp.getTarget().getClass().getSimpleName()));
	    log.setOpeMethod(String.valueOf(jp.getStaticPart().toShortString()));
	    log.setOpeTime(new Date());
		NoteExplain clsNote=jp.getTarget().getClass().getAnnotation(NoteExplain.class);
	    log.setOpeSerName(clsNote.comment());
	    Object[] objParas=jp.getArgs();
	    DbEntity de=objParas[0].getClass().getAnnotation(DbEntity.class);
	    String metName="新增"+de.comment();
	    boolean secret=false;
		try{
			Field f=jp.getStaticPart().getClass().getDeclaredField("methodInvocation");
			f.setAccessible(true);
			MethodInvocation mi=(MethodInvocation)f.get(jp.getStaticPart());
			NoteExplain metNote=mi.getMethod().getAnnotation(NoteExplain.class);
			metName=metNote.comment();
			secret=metNote.secret();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	    log.setOpeMetName(metName);
	    log.setOpeTable(de.table());
	    String paras="内容有关用户隐私，此处不做展示";
	    if(!secret){
	    	StringBuilder sbDesc=new StringBuilder();
		    for(Field f:objParas[0].getClass().getDeclaredFields()){
		    	DbField df=f.getAnnotation(DbField.class);
		    	String value=null;
		    	try{
		    		f.setAccessible(true);
		    		value=f.get(objParas[0]).toString();
		    	}catch(Exception ex){}
		    	if(value!=null && !value.equals("") && df.meaning() && df.export()){
		    		sbDesc.append(df.comment()).append(":").append(value).append(",");
		    	}
		    }
		    paras="["+sbDesc.toString().substring(0,sbDesc.toString().length()-1)+"]";
	    }
	    log.setOpeParas(paras);
	    log.setLgnLogId(String.valueOf(objParas[1]));
	    logMapper.insertOperatorLog(log);
	}
	
	@AfterReturning("execution(* com.goodfox.*.*.*.service.impl.*.modify*(..))")
	public void modifyLogging(JoinPoint jp){
		logger.debug("获取更新操作日志");
		OperatorLog log=new OperatorLog();
		log.setOpeLogId(UUIDUtil.getUUID());
	    log.setOpeService(String.valueOf(jp.getTarget().getClass().getSimpleName()));
	    log.setOpeMethod(String.valueOf(jp.getStaticPart().toShortString()));
	    log.setOpeTime(new Date());
	    NoteExplain clsNote=jp.getTarget().getClass().getAnnotation(NoteExplain.class);
	    log.setOpeSerName(clsNote.comment());
	    Object[] objParas=jp.getArgs();
	    DbEntity de=objParas[0].getClass().getAnnotation(DbEntity.class);
	    String metName="更新"+de.comment();
	    boolean secret=false;
		try{
			Field f=jp.getStaticPart().getClass().getDeclaredField("methodInvocation");
			f.setAccessible(true);
			MethodInvocation mi=(MethodInvocation)f.get(jp.getStaticPart());
			NoteExplain metNote=mi.getMethod().getAnnotation(NoteExplain.class);
			metName=metNote.comment();
			secret=metNote.secret();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	    log.setOpeMetName(metName);
	    log.setOpeTable(de.table());
	    String paras="内容有关用户隐私，此处不做展示";
	    if(!secret){
		    StringBuilder sbBefore=new StringBuilder();
		    for(Field f:objParas[0].getClass().getDeclaredFields()){
		    	DbField df=f.getAnnotation(DbField.class);
		    	String value=null;
		    	try{
		    		f.setAccessible(true);
		    		value=f.get(objParas[0]).toString();
		    	}catch(Exception ex){}
		    	if(value!=null && !value.equals("") && df.meaning() && df.export()){
		    		sbBefore.append(df.comment()).append(":").append(value).append(",");
		    	}
		    }
		    String sBefore="更新前:["+sbBefore.toString().substring(0,sbBefore.toString().length()-1)+"];";
		    StringBuilder sbAfter=new StringBuilder();
		    for(Field f:objParas[1].getClass().getDeclaredFields()){
		    	DbField df=f.getAnnotation(DbField.class);
		    	String value=null;
		    	try{
		    		f.setAccessible(true);
		    		value=f.get(objParas[1]).toString();
		    	}catch(Exception ex){}
		    	if(value!=null && !value.equals("") && df.meaning() && df.export()){
		    		sbAfter.append(df.comment()).append(":").append(value).append(",");
		    	}
		    }
		    String sAfter="更新后:["+sbAfter.toString().substring(0,sbAfter.toString().length()-1)+"]";
		    paras=sBefore+sAfter;
	    }
	    log.setOpeParas(paras);
	    log.setLgnLogId(String.valueOf(objParas[2]));
	    logMapper.insertOperatorLog(log);
	}
	
	@AfterReturning("execution(* com.goodfox.*.*.*.service.impl.*.remove*(..))")
	public void removeLogging(JoinPoint jp){
		logger.debug("获取移除操作日志");
		OperatorLog log=new OperatorLog();
		log.setOpeLogId(UUIDUtil.getUUID());
	    log.setOpeService(String.valueOf(jp.getTarget().getClass().getSimpleName()));
	    log.setOpeMethod(String.valueOf(jp.getStaticPart().toShortString()));
	    log.setOpeTime(new Date());
		NoteExplain clsNote=jp.getTarget().getClass().getAnnotation(NoteExplain.class);
	    log.setOpeSerName(clsNote.comment());
	    Object[] objParas=jp.getArgs();
	    DbEntity de=objParas[0].getClass().getAnnotation(DbEntity.class);
	    String metName="移除"+de.comment();
	    boolean secret=false;
		try{
			Field f=jp.getStaticPart().getClass().getDeclaredField("methodInvocation");
			f.setAccessible(true);
			MethodInvocation mi=(MethodInvocation)f.get(jp.getStaticPart());
			NoteExplain metNote=mi.getMethod().getAnnotation(NoteExplain.class);
			metName=metNote.comment();
			secret=metNote.secret();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	    log.setOpeMetName(metName);
	    log.setOpeTable(de.table());
	    String paras="内容有关用户隐私，此处不做展示";
	    if(!secret){
		    StringBuilder sbDesc=new StringBuilder();
		    for(Field f:objParas[0].getClass().getDeclaredFields()){
		    	DbField df=f.getAnnotation(DbField.class);
		    	String value=null;
		    	try{
		    		f.setAccessible(true);
		    		value=f.get(objParas[0]).toString();
		    	}catch(Exception ex){}
		    	if(value!=null && !value.equals("") && df.meaning() && df.export()){
		    		sbDesc.append(df.comment()).append(":").append(value).append(",");
		    	}
		    }
		    paras="["+sbDesc.toString().substring(0,sbDesc.toString().length()-1)+"]";
	    }
	    log.setOpeParas(paras);
	    log.setLgnLogId(String.valueOf(objParas[1]));
	    logMapper.insertOperatorLog(log);
	}
}
